home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / aplictns / dkbtrace / part05 < prev    next >
Encoding:
Internet Message Format  |  1990-09-03  |  66.0 KB

  1. Path: abcfd20.larc.nasa.gov!amiga-request
  2. From: amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator)
  3. Subject: v90i253: DKBTrace 2.01 - DKBtrace Ray-Tracer, Part05/10
  4. Reply-To: David Schanen <mtv@milton.u.washington.edu>
  5. Newsgroups: comp.sources.amiga
  6. Message-ID: <comp.sources.amiga:v90i253@abcfd20.larc.nasa.gov>
  7. References: <comp.sources.amiga:v90i249@abcfd20.larc.nasa.gov>
  8. Date: 03 Sep 90 23:22:06 GMT
  9. Approved: tadguy@uunet.UU.NET (Tad Guy)
  10. X-Mail-Submissions-To: amiga@uunet.uu.net
  11. X-Post-Discussions-To: comp.sys.amiga
  12.  
  13. Submitted-by: David Schanen <mtv@milton.u.washington.edu>
  14. Posting-number: Volume 90, Issue 253
  15. Archive-name: applications/dkbtrace-2.01/part05
  16.  
  17. #!/bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 5 (of 10)."
  24. # Contents:  src/frame.h src/gifdecod.c src/render.c src/trace.c
  25. # Wrapped by tadguy@abcfd20 on Mon Sep  3 19:21:19 1990
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'src/frame.h' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'src/frame.h'\"
  29. else
  30. echo shar: Extracting \"'src/frame.h'\" \(14642 characters\)
  31. sed "s/^X//" >'src/frame.h' <<'END_OF_FILE'
  32. X/*****************************************************************************
  33. X*
  34. X*                                   frame.h
  35. X*
  36. X*   from DKBTrace (c) 1990  David Buck
  37. X*
  38. X*  This header file is included by all C modules in DKBTrace.  It defines all
  39. X*  globally-accessible types and constants.
  40. X*
  41. X* This software is freely distributable. The source and/or object code may be
  42. X* copied or uploaded to communications services so long as this notice remains
  43. X* at the top of each file.  If any changes are made to the program, you must
  44. X* clearly indicate in the documentation and in the programs startup message
  45. X* who it was who made the changes. The documentation should also describe what
  46. X* those changes were. This software may not be included in whole or in
  47. X* part into any commercial package without the express written consent of the
  48. X* author.  It may, however, be included in other public domain or freely
  49. X* distributed software so long as the proper credit for the software is given.
  50. X*
  51. X* This software is provided as is without any guarantees or warranty. Although
  52. X* the author has attempted to find and correct any bugs in the software, he
  53. X* is not responsible for any damage caused by the use of the software.  The
  54. X* author is under no obligation to provide service, corrections, or upgrades
  55. X* to this package.
  56. X*
  57. X* Despite all the legal stuff above, if you do find bugs, I would like to hear
  58. X* about them.  Also, if you have any comments or questions, you may contact me
  59. X* at the following address:
  60. X*
  61. X*     David Buck
  62. X*     22C Sonnet Cres.
  63. X*     Nepean Ontario
  64. X*     Canada, K2H 8W7
  65. X*
  66. X*  I can also be reached on the following bulleton boards:
  67. X*
  68. X*     ATX              (613) 526-4141
  69. X*     OMX              (613) 731-3419
  70. X*     Mystic           (613) 731-0088 or (613) 731-6698
  71. X*
  72. X*  Fidonet:   1:163/109.9
  73. X*  Internet:  David_Buck@Carleton.CA
  74. X*
  75. X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  76. X*
  77. X*     Lattice BBS                      (708) 916-1200
  78. X*     The Information Exchange BBS     (708) 945-5575
  79. X*     Stillwaters BBS                  (708) 403-2826
  80. X*
  81. X*****************************************************************************/
  82. X
  83. X
  84. X/* Generic header for all modules */
  85. X
  86. X#include "config.h"
  87. X#include <stdio.h>
  88. X#include <string.h>
  89. X#include <math.h>
  90. X
  91. X#ifndef TRUE
  92. X#define TRUE 1
  93. X#define FALSE 0
  94. X#endif
  95. X
  96. X#ifndef FILE_NAME_LENGTH
  97. X#define FILE_NAME_LENGTH 150
  98. X#endif
  99. X
  100. X#ifndef DBL
  101. X#define DBL double
  102. X#endif
  103. X
  104. X#ifndef HUGE_VAL
  105. X#define HUGE_VAL 1.0e+17
  106. X#endif
  107. X
  108. X#ifndef DBL_FORMAT_STRING
  109. X#define DBL_FORMAT_STRING "%lf"
  110. X#endif
  111. X
  112. X#ifndef TEST_ABORT
  113. X#define TEST_ABORT
  114. X#endif
  115. X
  116. X/* These values determine the minumum and maximum distances
  117. X   that qualify as ray-object intersections */
  118. X#define Small_Tolerance 0.001
  119. X#define Max_Distance 1.0e7
  120. X
  121. X/* Maximum gif bitmap size allowed. */
  122. X#define BITMAP_X_SIZE 640
  123. X#define BITMAP_Y_SIZE 480
  124. X
  125. Xtypedef struct q_entry INTERSECTION;
  126. Xtypedef struct Vector_Struct VECTOR;
  127. Xtypedef DBL MATRIX [4][4];
  128. Xtypedef struct Colour_Struct COLOUR;
  129. Xtypedef struct Colour_Map_Entry COLOUR_MAP_ENTRY;
  130. Xtypedef struct Colour_Map_Struct COLOUR_MAP;
  131. Xtypedef struct Transformation_Struct TRANSFORMATION;
  132. Xtypedef struct Image_Struct IMAGE;
  133. Xtypedef struct Texture_Struct TEXTURE;
  134. Xtypedef struct Method_Struct METHODS;
  135. Xtypedef struct Viewpoint_Struct VIEWPOINT;
  136. Xtypedef struct Object_Shape SHAPE;
  137. Xtypedef struct Object_Struct OBJECT;
  138. Xtypedef struct Sphere_Shape SPHERE;
  139. Xtypedef struct Quadric_Shape QUADRIC;
  140. Xtypedef struct Triangle_Shape TRIANGLE;
  141. Xtypedef struct Smooth_Triangle_Shape SMOOTH_TRIANGLE;
  142. Xtypedef struct Plane_Shape PLANE;
  143. Xtypedef struct CSG_Type CSG_SHAPE;
  144. Xtypedef struct Composite_Object_Struct COMPOSITE;
  145. Xtypedef struct Ray_Struct RAY;
  146. Xtypedef struct Frame_Struct FRAME;
  147. Xtypedef struct prioq_struct PRIOQ;
  148. Xtypedef enum Token_Type TOKEN;
  149. Xtypedef enum Constant_Type CONSTANT;
  150. Xtypedef struct Chunk_Header_Struct CHUNK_HEADER;
  151. X
  152. Xstruct Vector_Struct
  153. X   {
  154. X   DBL x, y, z;
  155. X   };
  156. X
  157. X
  158. X
  159. Xstruct Colour_Struct
  160. X   {
  161. X   DBL Red, Green, Blue, Alpha;
  162. X   };
  163. X
  164. X
  165. Xstruct Colour_Map_Entry
  166. X   {
  167. X   DBL start, end;
  168. X   COLOUR Start_Colour, End_Colour;
  169. X   };
  170. X
  171. X
  172. Xstruct Colour_Map_Struct
  173. X   {
  174. X   int Number_Of_Entries;
  175. X   COLOUR_MAP_ENTRY *Colour_Map_Entries;
  176. X   };
  177. X
  178. X
  179. Xstruct Transformation_Struct
  180. X   {
  181. X   MATRIX matrix;
  182. X   MATRIX inverse;
  183. X   };
  184. X
  185. X
  186. Xstruct Image_Struct
  187. X   {
  188. X   DBL width, height;
  189. X   int iwidth, iheight;
  190. X   unsigned char *red, *green, *blue;
  191. X   };
  192. X
  193. X
  194. Xenum Texture_Type { NO_TEXTURE, BOZO_TEXTURE, MARBLE_TEXTURE, WOOD_TEXTURE, CHECKER_TEXTURE, SPOTTED_TEXTURE, AGATE_TEXTURE, GRANITE_TEXTURE, GRADIENT_TEXTURE, IMAGEMAP_TEXTURE } ;
  195. X
  196. Xenum Bump_Type { NO_BUMPS, WAVES, RIPPLES, WRINKLES, BUMPS, DENTS };
  197. X
  198. Xstruct Texture_Struct
  199. X   {
  200. X   DBL Object_Reflection;
  201. X   DBL Object_Ambient;
  202. X   DBL Object_Diffuse, Object_Brilliance;
  203. X   DBL Object_Index_Of_Refraction;
  204. X   DBL Object_Refraction;
  205. X   DBL Object_Specular, Object_Roughness;
  206. X   DBL Object_Phong, Object_PhongSize;
  207. X   DBL Bump_Amount;
  208. X   DBL Texture_Randomness;
  209. X   DBL Frequency;
  210. X   DBL Phase;
  211. X   enum Texture_Type Texture_Number ;
  212. X   enum Bump_Type Bump_Number;
  213. X   TRANSFORMATION *Texture_Transformation;
  214. X   COLOUR Colour1;
  215. X   COLOUR Colour2;
  216. X   DBL Turbulence;
  217. X   VECTOR Texture_Gradient;
  218. X   COLOUR_MAP *Colour_Map;
  219. X   IMAGE *Image;
  220. X   short Once_Flag;
  221. X   };
  222. X
  223. Xenum Object_Type {SPHERE_TYPE, TRIANGLE_TYPE, SMOOTH_TRIANGLE_TYPE, PLANE_TYPE,
  224. X                  QUADRIC_TYPE, COMPOSITE_TYPE, OBJECT_TYPE,
  225. X                  CSG_UNION_TYPE, CSG_INTERSECTION_TYPE, CSG_DIFFERENCE_TYPE,
  226. X                  VIEWPOINT_TYPE };
  227. X
  228. Xstruct Object_Struct
  229. X   {
  230. X   METHODS *Methods;
  231. X   enum Object_Type Type;
  232. X   struct Object_Struct *Next_Object;
  233. X   struct Object_Struct *Next_Light_Source;
  234. X   SHAPE *Bounding_Shapes;
  235. X   SHAPE *Shape;
  236. X   char Light_Source_Flag;
  237. X   char Transparency;
  238. X   VECTOR  Object_Center;
  239. X   COLOUR Object_Colour;
  240. X   TEXTURE *Object_Texture;
  241. X   };
  242. X
  243. X
  244. Xtypedef INTERSECTION *(*INTERSECTION_METHOD)PARAMS((OBJECT *, RAY *));
  245. Xtypedef int (*ALL_INTERSECTIONS_METHOD)PARAMS((OBJECT *, RAY *, PRIOQ *));
  246. Xtypedef int (*INSIDE_METHOD)PARAMS((VECTOR *, OBJECT *));
  247. Xtypedef void (*NORMAL_METHOD)PARAMS((VECTOR *, OBJECT *, VECTOR *));
  248. Xtypedef void *(*COPY_METHOD)PARAMS((OBJECT *));
  249. Xtypedef void (*TRANSLATE_METHOD)PARAMS((OBJECT *, VECTOR *));
  250. Xtypedef void (*ROTATE_METHOD)PARAMS((OBJECT *, VECTOR *));
  251. Xtypedef void (*SCALE_METHOD)PARAMS((OBJECT *, VECTOR *));
  252. Xtypedef void (*INVERT_METHOD)PARAMS((OBJECT *));
  253. X
  254. Xstruct Method_Struct
  255. X   {
  256. X   INTERSECTION_METHOD Intersection_Method;
  257. X   ALL_INTERSECTIONS_METHOD All_Intersections_Method;
  258. X   INSIDE_METHOD Inside_Method;
  259. X   NORMAL_METHOD Normal_Method;
  260. X   COPY_METHOD Copy_Method;
  261. X   TRANSLATE_METHOD Translate_Method;
  262. X   ROTATE_METHOD Rotate_Method;
  263. X   SCALE_METHOD Scale_Method;
  264. X   INVERT_METHOD Invert_Method;
  265. X   };
  266. X
  267. X
  268. X#define All_Intersections(x,y,z) ((*((x)->Methods->All_Intersections_Method)) (x,y,z))
  269. X#define Intersection(x,y) ((*((x)->Methods->Intersection_Method)) (x,y))
  270. X#define Inside(x,y) ((*((y)->Methods->Inside_Method)) (x,y))
  271. X#define Normal(x,y,z) ((*((y)->Methods->Normal_Method)) (x,y,z))
  272. X#define Copy(x) ((*((x)->Methods->Copy_Method)) (x))
  273. X#define Translate(x,y) ((*((x)->Methods->Translate_Method)) (x,y))
  274. X#define Scale(x,y) ((*((x)->Methods->Scale_Method)) (x,y))
  275. X#define Rotate(x,y) ((*((x)->Methods->Rotate_Method)) (x,y))
  276. X#define Invert(x) ((*((x)->Methods->Invert_Method)) (x))
  277. X
  278. Xstruct Viewpoint_Struct
  279. X   {
  280. X   METHODS *Methods;
  281. X   enum Object_Type Type;
  282. X   VECTOR Location;
  283. X   VECTOR Direction;
  284. X   VECTOR Up;
  285. X   VECTOR Right;
  286. X   VECTOR Sky;
  287. X   };
  288. X
  289. X
  290. Xstruct Object_Shape
  291. X   {
  292. X   METHODS *Methods;
  293. X   enum Object_Type Type;
  294. X   struct Object_Shape *Next_Object;
  295. X   void *Parent_Object;
  296. X   };
  297. X
  298. X
  299. Xstruct Sphere_Shape
  300. X   {
  301. X   METHODS *Methods;
  302. X   enum Object_Type Type;
  303. X   SHAPE *Next_Object;
  304. X   OBJECT *Parent_Object;
  305. X   VECTOR  Center;
  306. X   DBL     Radius;
  307. X   DBL     Radius_Squared;
  308. X   DBL     Inverse_Radius;
  309. X   VECTOR  VPOtoC;
  310. X   DBL     VPOCSquared;
  311. X   short   VPinside, VPCached, Inverted;
  312. X   };
  313. X
  314. X
  315. Xstruct Quadric_Shape
  316. X   {
  317. X   METHODS *Methods;
  318. X   enum Object_Type Type;
  319. X   SHAPE *Next_Object;
  320. X   OBJECT *Parent_Object;
  321. X   VECTOR  Object_2_Terms;
  322. X   VECTOR  Object_Mixed_Terms;
  323. X   VECTOR  Object_Terms;
  324. X   DBL Object_Constant;
  325. X   DBL Object_VP_Constant;
  326. X   int Constant_Cached;
  327. X   int Non_Zero_Square_Term;
  328. X   };
  329. X
  330. X
  331. X#define X_AXIS 0
  332. X#define Y_AXIS 1
  333. X#define Z_AXIS 2
  334. X
  335. Xstruct Triangle_Shape
  336. X   {
  337. X   METHODS *Methods;
  338. X   enum Object_Type Type;
  339. X   SHAPE *Next_Object;
  340. X   OBJECT *Parent_Object;
  341. X   VECTOR  Normal_Vector;
  342. X   DBL     Distance;
  343. X   DBL     VPNormDotOrigin;
  344. X   unsigned int  VPCached:1;
  345. X   unsigned int  Dominant_Axis:2;
  346. X   unsigned int  Inverted:1;
  347. X   unsigned int  vAxis:2;         /* used only for smooth triangles */
  348. X   VECTOR  P1, P2, P3;
  349. X   };
  350. X
  351. X
  352. Xstruct Smooth_Triangle_Shape
  353. X   {
  354. X   METHODS *Methods;
  355. X   enum Object_Type Type;
  356. X   SHAPE *Next_Object;
  357. X   OBJECT *Parent_Object;
  358. X   VECTOR  Normal_Vector;
  359. X   DBL     Distance;
  360. X   DBL     VPNormDotOrigin;
  361. X   unsigned int  VPCached:1;
  362. X   unsigned int  Dominant_Axis:2;
  363. X   unsigned int  Inverted:1;
  364. X   unsigned int  vAxis:2;         /* used only for smooth triangles */
  365. X   VECTOR  P1, P2, P3;
  366. X   VECTOR  N1, DN12, DN13, Perp;
  367. X   DBL  BaseDelta;
  368. X   };
  369. X
  370. X
  371. X
  372. Xstruct Plane_Shape
  373. X   {
  374. X   METHODS *Methods;
  375. X   enum Object_Type Type;
  376. X   SHAPE *Next_Object;
  377. X   OBJECT *Parent_Object;
  378. X   VECTOR  Normal_Vector;
  379. X   DBL     Distance;
  380. X   DBL     VPNormDotOrigin;
  381. X   int     VPCached;
  382. X   };
  383. X
  384. X
  385. Xstruct CSG_Type
  386. X   {
  387. X   METHODS *Methods;
  388. X   enum Object_Type Type;
  389. X   SHAPE *Next_Object;
  390. X   OBJECT *Parent_Object;
  391. X   SHAPE *Shapes;
  392. X   };
  393. X   
  394. X
  395. Xstruct Composite_Object_Struct
  396. X   {
  397. X   METHODS *Methods;
  398. X   enum Object_Type Type;
  399. X   OBJECT *Next_Object;
  400. X   OBJECT *Next_Light_Source;
  401. X   SHAPE *Bounding_Shapes;
  402. X   OBJECT *Objects;
  403. X   };
  404. X
  405. X
  406. X#define MAX_CONTAINING_OBJECTS 5
  407. X
  408. Xstruct Ray_Struct
  409. X   {
  410. X   VECTOR Initial;               /*  Xo  Yo  Zo  */
  411. X   VECTOR Direction;             /*  Xv  Yv  Zv  */
  412. X   VECTOR Initial_2;             /*  Xo^2  Yo^2  Zo^2  */
  413. X   VECTOR Direction_2;           /*  Xv^2  Yv^2  Zv^2  */
  414. X   VECTOR Initial_Direction;     /*  XoXv  YoYv  ZoZv  */
  415. X   VECTOR Mixed_Initial_Initial; /*  XoYo  XoZo  YoZo  */
  416. X   VECTOR Mixed_Dir_Dir;         /*  XvYv  XvZv  YvZv  */
  417. X   VECTOR Mixed_Init_Dir;        /*  XoYv+XvYo  XoZv+XvZo  YoZv+YvZo  */
  418. X   int Containing_Index;
  419. X   OBJECT *Containing_Objects [MAX_CONTAINING_OBJECTS];
  420. X   DBL Containing_IORs [MAX_CONTAINING_OBJECTS];
  421. X   int Quadric_Constants_Cached;
  422. X   };
  423. X
  424. X
  425. Xstruct Frame_Struct
  426. X   {
  427. X   VIEWPOINT View_Point;
  428. X   int Screen_Height, Screen_Width;
  429. X   OBJECT *Light_Sources;
  430. X   OBJECT *Objects;
  431. X   DBL Atmosphere_IOR, Antialias_Threshold;
  432. X   DBL Fog_Distance;
  433. X   COLOUR Fog_Colour;
  434. X   };
  435. X
  436. X
  437. X#define DISPLAY 1
  438. X#define VERBOSE 2
  439. X#define DISKWRITE 4
  440. X#define PROMPTEXIT 8
  441. X#define ANTIALIAS 16
  442. X#define DEBUGGING 32
  443. X#define RGBSEPARATE 64
  444. X#define TARGA 128
  445. X#define EXITENABLE 256
  446. X
  447. X#define Make_Colour(c,r,g,b) { (c)->Red=(r);(c)->Green=(g);(c)->Blue=(b); (c)->Alpha=0.0; }
  448. X
  449. X#define Make_Vector(v,a,b,c) { (v)->x=(a);(v)->y=(b);(v)->z=(c); }
  450. X
  451. X/* Definitions for PRIOQ structure */
  452. X
  453. Xstruct q_entry
  454. X   {
  455. X   DBL Depth;
  456. X   OBJECT *Object;
  457. X   VECTOR Point;
  458. X   SHAPE *Shape;
  459. X   };
  460. X
  461. Xstruct prioq_struct
  462. X   {
  463. X   struct prioq_struct *next_pq;
  464. X   struct q_entry *queue;
  465. X   unsigned int current_entry, queue_size;
  466. X   };
  467. X
  468. X
  469. X/* Token Definitions for Parser */
  470. X
  471. Xenum Token_Type
  472. X   {
  473. X   AGATE_TOKEN,
  474. X   ALPHA_TOKEN,
  475. X   AMBIENT_TOKEN,
  476. X   AMPERSAND_TOKEN,
  477. X   AT_TOKEN,
  478. X   BACK_QUOTE_TOKEN,
  479. X   BACK_SLASH_TOKEN,
  480. X   BAR_TOKEN,
  481. X   BLUE_TOKEN,
  482. X   BRILLIANCE_TOKEN,
  483. X   BOZO_TOKEN,
  484. X   BOUNDED_TOKEN,
  485. X   BUMPS_TOKEN,
  486. X   CHECKER_TOKEN,
  487. X   COLON_TOKEN,
  488. X   COLOR_TOKEN,
  489. X   COLOUR_TOKEN,
  490. X   COLOR_MAP_TOKEN,
  491. X   COLOUR_MAP_TOKEN,
  492. X   COMMA_TOKEN,
  493. X   COMPOSITE_TOKEN,
  494. X   DASH_TOKEN,
  495. X   DECLARE_TOKEN,
  496. X   DENTS_TOKEN,
  497. X   DIFFERENCE_TOKEN,
  498. X   DIFFUSE_TOKEN,
  499. X   DIRECTION_TOKEN,
  500. X   DOLLAR_TOKEN,
  501. X   END_BOUNDED_TOKEN,
  502. X   END_COLOR_MAP_TOKEN,
  503. X   END_COLOUR_MAP_TOKEN,
  504. X   END_COMPOSITE_TOKEN,
  505. X   END_DIFFERENCE_TOKEN,
  506. X   END_FOG_TOKEN,
  507. X   END_INTERSECTION_TOKEN,
  508. X   END_OBJECT_TOKEN,
  509. X   END_OF_FILE_TOKEN,
  510. X   END_PLANE_TOKEN,
  511. X   END_POINTS_TOKEN,
  512. X   END_POLYGON_TOKEN,
  513. X   END_QUADRIC_TOKEN,
  514. X   END_SHAPE_TOKEN,
  515. X   END_SPHERE_TOKEN,
  516. X   END_TEXTURE_TOKEN,
  517. X   END_TRIANGLE_TOKEN,
  518. X   END_UNION_TOKEN,
  519. X   END_VIEW_POINT_TOKEN,
  520. X   EQUALS_TOKEN,
  521. X   EXCLAMATION_TOKEN,
  522. X   FLOAT_TOKEN,
  523. X   FOG_TOKEN,
  524. X   FREQUENCY_TOKEN,
  525. X   GIF_TOKEN,
  526. X   GRADIENT_TOKEN,
  527. X   GRANITE_TOKEN,
  528. X   GREEN_TOKEN,
  529. X   HASH_TOKEN,
  530. X   HAT_TOKEN,
  531. X   IDENTIFIER_TOKEN,
  532. X   IFF_TOKEN,
  533. X   IMAGEMAP_TOKEN,
  534. X   INCLUDE_TOKEN,
  535. X   INTERSECTION_TOKEN,
  536. X   INVERSE_TOKEN,
  537. X   IOR_TOKEN,
  538. X   LEFT_ANGLE_TOKEN,
  539. X   LEFT_BRACKET_TOKEN,
  540. X   LEFT_SQUARE_TOKEN,
  541. X   LIGHT_SOURCE_TOKEN,
  542. X   LOCATION_TOKEN,
  543. X   LOOK_AT_TOKEN,
  544. X   MARBLE_TOKEN,
  545. X   OBJECT_TOKEN,
  546. X   ONCE_TOKEN,
  547. X   PERCENT_TOKEN,
  548. X   PHASE_TOKEN,
  549. X   PHONG_TOKEN,
  550. X   PHONGSIZE_TOKEN,
  551. X   PLANE_TOKEN,
  552. X   PLUS_TOKEN,
  553. X   POINTS_TOKEN,
  554. X   POLYGON_TOKEN,
  555. X   QUADRIC_TOKEN,
  556. X   QUESTION_TOKEN,
  557. X   RAW_TOKEN,
  558. X   RED_TOKEN,
  559. X   REFLECTION_TOKEN,
  560. X   REFRACTION_TOKEN,
  561. X   REVOLVE_TOKEN,
  562. X   RIGHT_TOKEN,
  563. X   RIGHT_ANGLE_TOKEN,
  564. X   RIGHT_BRACKET_TOKEN,
  565. X   RIGHT_SQUARE_TOKEN,
  566. X   RIPPLES_TOKEN,
  567. X   ROTATE_TOKEN,
  568. X   ROUGHNESS_TOKEN,
  569. X   SCALE_TOKEN,
  570. X   SEMI_COLON_TOKEN,
  571. X   SHAPE_TOKEN,
  572. X   SINGLE_QUOTE_TOKEN,
  573. X   SIZE_TOKEN,
  574. X   SKY_TOKEN,
  575. X   SLASH_TOKEN,
  576. X   SMOOTH_TRIANGLE_TOKEN,
  577. X   SPECULAR_TOKEN,
  578. X   SPHERE_TOKEN,
  579. X   SPOTTED_TOKEN,
  580. X   STAR_TOKEN,
  581. X   STRING_TOKEN,
  582. X   TEXTURE_TOKEN,
  583. X   TILDE_TOKEN,
  584. X   TRANSLATE_TOKEN,
  585. X   TRIANGLE_TOKEN,
  586. X   TURBULENCE_TOKEN,
  587. X   UNION_TOKEN,
  588. X   UP_TOKEN,
  589. X   VIEW_POINT_TOKEN,
  590. X   WAVES_TOKEN,
  591. X   WOOD_TOKEN,
  592. X   WRINKLES_TOKEN,
  593. X   LAST_TOKEN };
  594. X
  595. X
  596. Xstruct Reserved_Word_Struct
  597. X   {
  598. X   TOKEN Token_Number;
  599. X   char *Token_Name;
  600. X   };
  601. X
  602. X/* Here's where you dump the information on the current token (fm. PARSE.C) */
  603. X
  604. Xstruct Token_Struct
  605. X   {
  606. X   TOKEN Token_Id;
  607. X   int Token_Line_No;
  608. X   char Token_String[FILE_NAME_LENGTH];
  609. X   DBL Token_Float;
  610. X   int Identifier_Number;
  611. X   int Unget_Token, End_Of_File;
  612. X   };
  613. X
  614. X/* Types of constants allowed in DECLARE statement (fm. PARSE.C) */
  615. X
  616. Xenum Constant_Type
  617. X   {
  618. X   OBJECT_CONSTANT,
  619. X   VIEW_POINT_CONSTANT,
  620. X   VECTOR_CONSTANT,
  621. X   FLOAT_CONSTANT,
  622. X   COLOUR_CONSTANT,
  623. X   QUADRIC_CONSTANT,
  624. X   SPHERE_CONSTANT,
  625. X   PLANE_CONSTANT,
  626. X   TRIANGLE_CONSTANT,
  627. X   SMOOTH_TRIANGLE_CONSTANT,
  628. X   CSG_INTERSECTION_CONSTANT,
  629. X   CSG_UNION_CONSTANT,
  630. X   CSG_DIFFERENCE_CONSTANT,
  631. X   COMPOSITE_CONSTANT,
  632. X   TEXTURE_CONSTANT
  633. X   };
  634. X
  635. X
  636. Xstruct Constant_Struct
  637. X   {
  638. X   int Identifier_Number;
  639. X   CONSTANT Constant_Type;
  640. X   char *Constant_Data;
  641. X   };
  642. X
  643. X/* Types for reading IFF files. */
  644. Xtypedef struct {
  645. X   unsigned short Red, Green, Blue;
  646. X   } IMAGE_COLOUR;
  647. X
  648. Xstruct Chunk_Header_Struct {
  649. X   long name;
  650. X   long size;
  651. X   };
  652. END_OF_FILE
  653. if test 14642 -ne `wc -c <'src/frame.h'`; then
  654.     echo shar: \"'src/frame.h'\" unpacked with wrong size!
  655. fi
  656. # end of 'src/frame.h'
  657. fi
  658. if test -f 'src/gifdecod.c' -a "${1}" != "-c" ; then 
  659.   echo shar: Will not clobber existing file \"'src/gifdecod.c'\"
  660. else
  661. echo shar: Extracting \"'src/gifdecod.c'\" \(15767 characters\)
  662. sed "s/^X//" >'src/gifdecod.c' <<'END_OF_FILE'
  663. X/*****************************************************************************
  664. X*
  665. X*                                   gifdecod.c
  666. X*
  667. X*   from DKBTrace (c) 1990  David Buck
  668. X*
  669. X* This software is freely distributable. The source and/or object code may be
  670. X* copied or uploaded to communications services so long as this notice remains
  671. X* at the top of each file.  If any changes are made to the program, you must
  672. X* clearly indicate in the documentation and in the programs startup message
  673. X* who it was who made the changes. The documentation should also describe what
  674. X* those changes were. This software may not be included in whole or in
  675. X* part into any commercial package without the express written consent of the
  676. X* author.  It may, however, be included in other public domain or freely
  677. X* distributed software so long as the proper credit for the software is given.
  678. X*
  679. X* This software is provided as is without any guarantees or warranty. Although
  680. X* the author has attempted to find and correct any bugs in the software, he
  681. X* is not responsible for any damage caused by the use of the software.  The
  682. X* author is under no obligation to provide service, corrections, or upgrades
  683. X* to this package.
  684. X*
  685. X* Despite all the legal stuff above, if you do find bugs, I would like to hear
  686. X* about them.  Also, if you have any comments or questions, you may contact me
  687. X* at the following address:
  688. X*
  689. X*     David Buck
  690. X*     22C Sonnet Cres.
  691. X*     Nepean Ontario
  692. X*     Canada, K2H 8W7
  693. X*
  694. X*  I can also be reached on the following bulleton boards:
  695. X*
  696. X*     ATX              (613) 526-4141
  697. X*     OMX              (613) 731-3419
  698. X*     Mystic           (613) 731-0088 or (613) 731-6698
  699. X*
  700. X*  Fidonet:   1:163/109.9
  701. X*  Internet:  David_Buck@Carleton.CA
  702. X*
  703. X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  704. X*
  705. X*     Lattice BBS                      (708) 916-1200
  706. X*     The Information Exchange BBS     (708) 945-5575
  707. X*     Stillwaters BBS                  (708) 403-2826
  708. X*
  709. X*****************************************************************************/
  710. X
  711. X/*
  712. X   This module was freely borrowed from FRACTINT, so here is their entire
  713. X   copyright to keep them happy:
  714. X*/
  715. X
  716. X/* DECODER.C - An LZW decoder for GIF
  717. X * Copyright (C) 1987, by Steven A. Bennett
  718. X *
  719. X * Permission is given by the author to freely redistribute and include
  720. X * this code in any program as long as this credit is given where due.
  721. X *
  722. X * In accordance with the above, I want to credit Steve Wilhite who wrote
  723. X * the code which this is heavily inspired by...
  724. X *
  725. X * GIF and 'Graphics Interchange Format' are trademarks (tm) of
  726. X * Compuserve, Incorporated, an H&R Block Company.
  727. X *
  728. X * Release Notes: This file contains a decoder routine for GIF images
  729. X * which is similar, structurally, to the original routine by Steve Wilhite.
  730. X * It is, however, somewhat noticably faster in most cases.
  731. X *
  732. X == This routine was modified for use in FRACTINT in two ways.
  733. X == 
  734. X == 1) The original #includes were folded into the routine strictly to hold
  735. X ==    down the number of files we were dealing with.
  736. X ==
  737. X == 2) The 'stack', 'suffix', 'prefix', and 'buf' arrays were changed from
  738. X ==    static and 'malloc()'ed to external only so that the assembler
  739. X ==    program could use the same array space for several independent
  740. X ==    chunks of code.  Also, 'stack' was renamed to 'dstack' for TASM
  741. X ==    compatibility.
  742. X == 
  743. X == 3) The 'out_line()' external function has been changed to reference 
  744. X ==    '*outln()' for flexibility (in particular, 3D transformations)
  745. X ==
  746. X == 4) A call to 'keypressed()' has been added after the 'outln()' calls
  747. X ==    to check for the presenc of a key-press as a bail-out signal
  748. X ==
  749. X == (Bert Tyler and Timothy Wegner)
  750. X*/
  751. X
  752. X/* 
  753. X   This routine was modified for DKBtrace in the following ways:
  754. X
  755. X   1)  Removed calls to buzzer() and keypressed() to get rid of ASM files.
  756. X
  757. X   2)  The dstack, suffix, and prefix arrays were made STATIC once again.
  758. X
  759. X   3)  Added the usual ANSI function prototypes, etc. in the DKB headers.
  760. X*/
  761. X
  762. X#include "frame.h"
  763. X#include "dkbproto.h"
  764. X
  765. X#define LOCAL static
  766. X#define IMPORT extern
  767. X
  768. X#define FAST register
  769. X
  770. Xtypedef short WORD;
  771. Xtypedef unsigned short UWORD;
  772. Xtypedef char TEXT;
  773. Xtypedef unsigned char UTINY;
  774. Xtypedef long LONG;
  775. Xtypedef unsigned long ULONG;
  776. Xtypedef int INT;
  777. X
  778. X
  779. X/* Various error codes used by decoder
  780. X * and my own routines...   It's okay
  781. X * for you to define whatever you want,
  782. X * as long as it's negative...  It will be
  783. X * returned intact up the various subroutine
  784. X * levels...
  785. X */
  786. X#define OUT_OF_MEMORY -10
  787. X#define BAD_CODE_SIZE -20
  788. X#define READ_ERROR -1
  789. X#define WRITE_ERROR -2
  790. X#define OPEN_ERROR -3
  791. X#define CREATE_ERROR -4
  792. X
  793. X
  794. X/* IMPORT INT get_byte()
  795. X *
  796. X *   - This external (machine specific) function is expected to return
  797. X * either the next byte from the GIF file, or a negative number, as
  798. X * defined in ERRS.H.
  799. X */
  800. XIMPORT INT get_byte();
  801. X
  802. X/* IMPORT INT out_line(pixels, linelen)
  803. X *     UBYTE pixels[];
  804. X *     INT linelen;
  805. X *
  806. X *   - This function takes a full line of pixels (one byte per pixel) and
  807. X * displays them (or does whatever your program wants with them...).  It
  808. X * should return zero, or negative if an error or some other event occurs
  809. X * which would require aborting the decode process...  Note that the length
  810. X * passed will almost always be equal to the line length passed to the
  811. X * decoder function, with the sole exception occurring when an ending code
  812. X * occurs in an odd place in the GIF file...  In any case, linelen will be
  813. X * equal to the number of pixels passed...
  814. X */
  815. XIMPORT INT out_line();
  816. X
  817. X/* IMPORT INT bad_code_count;
  818. X *
  819. X * This value is the only other global required by the using program, and
  820. X * is incremented each time an out of range code is read by the decoder.
  821. X * When this value is non-zero after a decode, your GIF file is probably
  822. X * corrupt in some way...
  823. X */
  824. XINT bad_code_count;
  825. X
  826. X#define NULL   0L
  827. X#define MAX_CODES   4095
  828. X
  829. X/* Static variables */
  830. XLOCAL WORD curr_size;                     /* The current code size */
  831. XLOCAL WORD clear;                         /* Value for a clear code */
  832. XLOCAL WORD ending;                        /* Value for a ending code */
  833. XLOCAL WORD newcodes;                      /* First available code */
  834. XLOCAL WORD top_slot;                      /* Highest code for current size */
  835. XLOCAL WORD slot;                          /* Last read code */
  836. X
  837. X/* The following static variables are used
  838. X * for seperating out codes
  839. X */
  840. XLOCAL WORD navail_bytes = 0;              /* # bytes left in block */
  841. XLOCAL WORD nbits_left = 0;                /* # bits left in current byte */
  842. XLOCAL UTINY b1;                           /* Current byte */
  843. XLOCAL UTINY byte_buff[257];               /* Current block */
  844. XLOCAL UTINY *pbytes;                      /* Pointer to next byte in block */
  845. X
  846. XLOCAL LONG code_mask[13] = {
  847. X     0,
  848. X     0x0001, 0x0003,
  849. X     0x0007, 0x000F,
  850. X     0x001F, 0x003F,
  851. X     0x007F, 0x00FF,
  852. X     0x01FF, 0x03FF,
  853. X     0x07FF, 0x0FFF
  854. X     };
  855. X
  856. X
  857. X/* This function initializes the decoder for reading a new image.
  858. X */
  859. XLOCAL WORD init_exp(size)
  860. X   WORD size;
  861. X   {
  862. X   curr_size = size + 1;
  863. X   top_slot = 1 << curr_size;
  864. X   clear = 1 << size;
  865. X   ending = clear + 1;
  866. X   slot = newcodes = ending + 1;
  867. X   navail_bytes = nbits_left = 0;
  868. X   return(0);
  869. X   }
  870. X
  871. X/* get_next_code()
  872. X * - gets the next code from the GIF file.  Returns the code, or else
  873. X * a negative number in case of file errors...
  874. X */
  875. XLOCAL WORD get_next_code()
  876. X   {
  877. X   WORD i, x;
  878. X   ULONG ret;
  879. X
  880. X   if (nbits_left == 0)
  881. X      {
  882. X      if (navail_bytes <= 0)
  883. X         {
  884. X
  885. X         /* Out of bytes in current block, so read next block
  886. X          */
  887. X         pbytes = byte_buff;
  888. X         if ((navail_bytes = get_byte()) < 0)
  889. X            return(navail_bytes);
  890. X         else if (navail_bytes)
  891. X            {
  892. X            for (i = 0; i < navail_bytes; ++i)
  893. X               {
  894. X               if ((x = get_byte()) < 0)
  895. X                  return(x);
  896. X               byte_buff[i] = x;
  897. X               }
  898. X            }
  899. X         }
  900. X      b1 = *pbytes++;
  901. X      nbits_left = 8;
  902. X      --navail_bytes;
  903. X      }
  904. X
  905. X   ret = b1 >> (8 - nbits_left);
  906. X   while (curr_size > nbits_left)
  907. X      {
  908. X      if (navail_bytes <= 0)
  909. X         {
  910. X
  911. X         /* Out of bytes in current block, so read next block
  912. X          */
  913. X         pbytes = byte_buff;
  914. X         if ((navail_bytes = get_byte()) < 0)
  915. X            return(navail_bytes);
  916. X         else if (navail_bytes)
  917. X            {
  918. X            for (i = 0; i < navail_bytes; ++i)
  919. X               {
  920. X               if ((x = get_byte()) < 0)
  921. X                  return(x);
  922. X               byte_buff[i] = x;
  923. X               }
  924. X            }
  925. X         }
  926. X      b1 = *pbytes++;
  927. X      ret |= b1 << nbits_left;
  928. X      nbits_left += 8;
  929. X      --navail_bytes;
  930. X      }
  931. X   nbits_left -= curr_size;
  932. X   ret &= code_mask[curr_size];
  933. X   return((WORD)(ret));
  934. X   }
  935. X
  936. X
  937. X/* The reason we have these seperated like this instead of using
  938. X * a structure like the original Wilhite code did, is because this
  939. X * stuff generally produces significantly faster code when compiled...
  940. X * This code is full of similar speedups...  (For a good book on writing
  941. X * C for speed or for space optomisation, see Efficient C by Tom Plum,
  942. X * published by Plum-Hall Associates...)
  943. X */
  944. X
  945. X/*
  946. XI removed the LOCAL identifiers in the arrays below and replaced them
  947. Xwith 'extern's so as to declare (and re-use) the space elsewhere.
  948. XThe arrays are actually declared in the assembler source.
  949. X                                                    Bert Tyler
  950. X*/
  951. X
  952. XLOCAL UTINY dstack[MAX_CODES + 1];      /* Stack for storing pixels */
  953. XLOCAL UTINY suffix[MAX_CODES + 1];      /* Suffix table */
  954. XLOCAL UWORD prefix[MAX_CODES + 1];      /* Prefix linked list */
  955. Xextern UTINY *decoderline;              /* decoded line goes here */
  956. X
  957. X/* WORD decoder(linewidth)
  958. X *    WORD linewidth;               * Pixels per line of image *
  959. X *
  960. X * - This function decodes an LZW image, according to the method used
  961. X * in the GIF spec.  Every *linewidth* "characters" (ie. pixels) decoded
  962. X * will generate a call to out_line(), which is a user specific function
  963. X * to display a line of pixels.  The function gets its codes from
  964. X * get_next_code() which is responsible for reading blocks of data and
  965. X * seperating them into the proper size codes.  Finally, get_byte() is
  966. X * the global routine to read the next byte from the GIF file.
  967. X *
  968. X * It is generally a good idea to have linewidth correspond to the actual
  969. X * width of a line (as specified in the Image header) to make your own
  970. X * code a bit simpler, but it isn't absolutely necessary.
  971. X *
  972. X * Returns: 0 if successful, else negative.  (See ERRS.H)
  973. X *
  974. X */
  975. X
  976. XWORD decoder(linewidth)
  977. X   WORD linewidth;
  978. X   {
  979. X   FAST UTINY *sp, *bufptr;
  980. X   UTINY *buf;
  981. X   FAST WORD code, fc, oc, bufcnt;
  982. X   WORD c, size, ret;
  983. X
  984. X   /* Initialize for decoding a new image...
  985. X    */
  986. X   if ((size = get_byte()) < 0)
  987. X      return(size);
  988. X   if (size < 2 || 9 < size)
  989. X      return(BAD_CODE_SIZE);
  990. X   init_exp(size);
  991. X
  992. X   /* Initialize in case they forgot to put in a clear code.
  993. X    * (This shouldn't happen, but we'll try and decode it anyway...)
  994. X    */
  995. X   oc = fc = 0;
  996. X
  997. X   buf = decoderline;
  998. X
  999. X   /* Set up the stack pointer and decode buffer pointer
  1000. X    */
  1001. X   sp = dstack;
  1002. X   bufptr = buf;
  1003. X   bufcnt = linewidth;
  1004. X
  1005. X   /* This is the main loop.  For each code we get we pass through the
  1006. X    * linked list of prefix codes, pushing the corresponding "character" for
  1007. X    * each code onto the stack.  When the list reaches a single "character"
  1008. X    * we push that on the stack too, and then start unstacking each
  1009. X    * character for output in the correct order.  Special handling is
  1010. X    * included for the clear code, and the whole thing ends when we get
  1011. X    * an ending code.
  1012. X    */
  1013. X   while ((c = get_next_code()) != ending)
  1014. X      {
  1015. X
  1016. X      /* If we had a file error, return without completing the decode
  1017. X       */
  1018. X      if (c < 0)
  1019. X         return(0);
  1020. X
  1021. X      /* If the code is a clear code, reinitialize all necessary items.
  1022. X       */
  1023. X      if (c == clear)
  1024. X         {
  1025. X         curr_size = size + 1;
  1026. X         slot = newcodes;
  1027. X         top_slot = 1 << curr_size;
  1028. X
  1029. X         /* Continue reading codes until we get a non-clear code
  1030. X          * (Another unlikely, but possible case...)
  1031. X          */
  1032. X         while ((c = get_next_code()) == clear)
  1033. X            ;
  1034. X
  1035. X         /* If we get an ending code immediately after a clear code
  1036. X          * (Yet another unlikely case), then break out of the loop.
  1037. X          */
  1038. X         if (c == ending)
  1039. X            break;
  1040. X
  1041. X         /* Finally, if the code is beyond the range of already set codes,
  1042. X          * (This one had better NOT happen...  I have no idea what will
  1043. X          * result from this, but I doubt it will look good...) then set it
  1044. X          * to color zero.
  1045. X          */
  1046. X         if (c >= slot)
  1047. X            c = 0;
  1048. X
  1049. X         oc = fc = c;
  1050. X
  1051. X         /* And let us not forget to put the char into the buffer... And
  1052. X          * if, on the off chance, we were exactly one pixel from the end
  1053. X          * of the line, we have to send the buffer to the out_line()
  1054. X          * routine...
  1055. X          */
  1056. X         *bufptr++ = c;
  1057. X         if (--bufcnt == 0)
  1058. X            {
  1059. X            if ((ret = out_line(buf, linewidth)) < 0)
  1060. X               return(ret);
  1061. X            bufptr = buf;
  1062. X            bufcnt = linewidth;
  1063. X            }
  1064. X         }
  1065. X      else
  1066. X         {
  1067. X
  1068. X         /* In this case, it's not a clear code or an ending code, so
  1069. X          * it must be a code code...  So we can now decode the code into
  1070. X          * a stack of character codes. (Clear as mud, right?)
  1071. X          */
  1072. X         code = c;
  1073. X
  1074. X         /* Here we go again with one of those off chances...  If, on the
  1075. X          * off chance, the code we got is beyond the range of those already
  1076. X          * set up (Another thing which had better NOT happen...) we trick
  1077. X          * the decoder into thinking it actually got the last code read.
  1078. X          * (Hmmn... I'm not sure why this works...  But it does...)
  1079. X          */
  1080. X         if (code >= slot)
  1081. X            {
  1082. X            if (code > slot)
  1083. X               ++bad_code_count;
  1084. X            code = oc;
  1085. X            *sp++ = fc;
  1086. X            }
  1087. X
  1088. X         /* Here we scan back along the linked list of prefixes, pushing
  1089. X          * helpless characters (ie. suffixes) onto the stack as we do so.
  1090. X          */
  1091. X         while (code >= newcodes)
  1092. X            {
  1093. X            *sp++ = suffix[code];
  1094. X            code = prefix[code];
  1095. X            }
  1096. X
  1097. X         /* Push the last character on the stack, and set up the new
  1098. X          * prefix and suffix, and if the required slot number is greater
  1099. X          * than that allowed by the current bit size, increase the bit
  1100. X          * size.  (NOTE - If we are all full, we *don't* save the new
  1101. X          * suffix and prefix...  I'm not certain if this is correct...
  1102. X          * it might be more proper to overwrite the last code...
  1103. X          */
  1104. X         *sp++ = code;
  1105. X         if (slot < top_slot)
  1106. X            {
  1107. X            suffix[slot] = fc = code;
  1108. X            prefix[slot++] = oc;
  1109. X            oc = c;
  1110. X            }
  1111. X         if (slot >= top_slot)
  1112. X            if (curr_size < 12)
  1113. X               {
  1114. X               top_slot <<= 1;
  1115. X               ++curr_size;
  1116. X               }
  1117. X
  1118. X         /* Now that we've pushed the decoded string (in reverse order)
  1119. X          * onto the stack, lets pop it off and put it into our decode
  1120. X          * buffer...  And when the decode buffer is full, write another
  1121. X          * line...
  1122. X          */
  1123. X         while (sp > dstack)
  1124. X            {
  1125. X            *bufptr++ = *(--sp);
  1126. X            if (--bufcnt == 0)
  1127. X               {
  1128. X               if ((ret = out_line(buf, linewidth)) < 0)
  1129. X                  return(ret);
  1130. X               bufptr = buf;
  1131. X               bufcnt = linewidth;
  1132. X               }
  1133. X            }
  1134. X         }
  1135. X      }
  1136. X   ret = 0;
  1137. X   if (bufcnt != linewidth)
  1138. X      ret = out_line(buf, (linewidth - bufcnt));
  1139. X   return(ret);
  1140. X   }
  1141. END_OF_FILE
  1142. if test 15767 -ne `wc -c <'src/gifdecod.c'`; then
  1143.     echo shar: \"'src/gifdecod.c'\" unpacked with wrong size!
  1144. fi
  1145. # end of 'src/gifdecod.c'
  1146. fi
  1147. if test -f 'src/render.c' -a "${1}" != "-c" ; then 
  1148.   echo shar: Will not clobber existing file \"'src/render.c'\"
  1149. else
  1150. echo shar: Extracting \"'src/render.c'\" \(16452 characters\)
  1151. sed "s/^X//" >'src/render.c' <<'END_OF_FILE'
  1152. X/*****************************************************************************
  1153. X*
  1154. X*                                    render.c
  1155. X*
  1156. X*   from DKBTrace (c) 1990  David Buck
  1157. X*
  1158. X*  This module implements the main raytracing loop.
  1159. X*
  1160. X* This software is freely distributable. The source and/or object code may be
  1161. X* copied or uploaded to communications services so long as this notice remains
  1162. X* at the top of each file.  If any changes are made to the program, you must
  1163. X* clearly indicate in the documentation and in the programs startup message
  1164. X* who it was who made the changes. The documentation should also describe what
  1165. X* those changes were. This software may not be included in whole or in
  1166. X* part into any commercial package without the express written consent of the
  1167. X* author.  It may, however, be included in other public domain or freely
  1168. X* distributed software so long as the proper credit for the software is given.
  1169. X*
  1170. X* This software is provided as is without any guarantees or warranty. Although
  1171. X* the author has attempted to find and correct any bugs in the software, he
  1172. X* is not responsible for any damage caused by the use of the software.  The
  1173. X* author is under no obligation to provide service, corrections, or upgrades
  1174. X* to this package.
  1175. X*
  1176. X* Despite all the legal stuff above, if you do find bugs, I would like to hear
  1177. X* about them.  Also, if you have any comments or questions, you may contact me
  1178. X* at the following address:
  1179. X*
  1180. X*     David Buck
  1181. X*     22C Sonnet Cres.
  1182. X*     Nepean Ontario
  1183. X*     Canada, K2H 8W7
  1184. X*
  1185. X*  I can also be reached on the following bulleton boards:
  1186. X*
  1187. X*     ATX              (613) 526-4141
  1188. X*     OMX              (613) 731-3419
  1189. X*     Mystic           (613) 731-0088 or (613) 731-6698
  1190. X*
  1191. X*  Fidonet:   1:163/109.9
  1192. X*  Internet:  David_Buck@Carleton.CA
  1193. X*
  1194. X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  1195. X*
  1196. X*     Lattice BBS                      (708) 916-1200
  1197. X*     The Information Exchange BBS     (708) 945-5575
  1198. X*     Stillwaters BBS                  (708) 403-2826
  1199. X*
  1200. X*****************************************************************************/
  1201. X
  1202. X
  1203. X#include "frame.h"
  1204. X#include "vector.h"
  1205. X#include "dkbproto.h"
  1206. X
  1207. Xextern FILE *bfp;
  1208. Xextern char Output_File_Name[30];
  1209. Xextern int File_Buffer_Size;
  1210. Xextern unsigned long Options;
  1211. Xextern int Quality;
  1212. Xvolatile int Stop_Flag;
  1213. Xextern int First_Line, Last_Line;
  1214. Xextern long Number_Of_Pixels, Number_Of_Rays, Number_Of_Pixels_Supersampled;
  1215. X
  1216. Xextern short *hashTable;
  1217. Xextern unsigned short crctab[256];
  1218. X#define rand3d(a,b) crctab[(int)(hashTable[(int)(hashTable[(int)((a)&0xfff)]^(b))&0xfff])&0xff]
  1219. X
  1220. XFRAME Frame;
  1221. XRAY *VP_Ray;
  1222. Xint Trace_Level;
  1223. X
  1224. X#define MAX_TRACE_LEVEL 5
  1225. X
  1226. Xvoid Create_Ray (ray, width, height, x, y)
  1227. X   RAY *ray;
  1228. X   int width, height;
  1229. X   DBL x, y;
  1230. X   {
  1231. X   register DBL X_Scalar, Y_Scalar;
  1232. X   VECTOR Temp_Vect_1, Temp_Vect_2;
  1233. X
  1234. X   /* Convert the X Coordinate to be a DBL from 0.0 to 1.0 */
  1235. X   X_Scalar = (x - (DBL) width / 2.0) / (DBL) width;
  1236. X
  1237. X   /* Convert the Y Coordinate to be a DBL from 0.0 to 1.0 */
  1238. X   Y_Scalar = (( (DBL)(Frame.Screen_Height - 1) - y) -
  1239. X          (DBL) height / 2.0) / (DBL) height;
  1240. X
  1241. X   VScale (Temp_Vect_1, Frame.View_Point.Up, Y_Scalar);
  1242. X   VScale (Temp_Vect_2, Frame.View_Point.Right, X_Scalar);
  1243. X   VAdd (ray->Direction, Temp_Vect_1, Temp_Vect_2);
  1244. X   VAdd (ray->Direction, ray->Direction, Frame.View_Point.Direction);
  1245. X   VNormalize (ray->Direction, ray->Direction);
  1246. X   Initialize_Ray_Containers (ray);
  1247. X   ray->Quadric_Constants_Cached = FALSE;
  1248. X   }
  1249. X
  1250. Xvoid Write_Line (Line, y)
  1251. X   COLOUR *Line;
  1252. X   int y;
  1253. X   {
  1254. X   char Red, Green, Blue, temp[2];
  1255. X   register int x;
  1256. X
  1257. X   if (!(Options & TARGA))    /* Write out line in DKB/QRT RAW format */
  1258. X      {
  1259. X      temp[0] = y % 256;
  1260. X      putc (temp[0], bfp);
  1261. X      temp[0] = y / 256;
  1262. X      putc (temp[0], bfp);
  1263. X
  1264. X      for (x = 0 ; x < Frame.Screen_Width ; x++) {
  1265. X         Red = (char) floor (Line[x].Red * 255.0);
  1266. X         putc (Red, bfp);
  1267. X         }
  1268. X
  1269. X      for (x = 0 ; x < Frame.Screen_Width ; x++) {
  1270. X         Green = (char) floor (Line[x].Green * 255.0);
  1271. X         putc (Green, bfp);
  1272. X         }
  1273. X
  1274. X      for (x = 0 ; x < Frame.Screen_Width ; x++) {
  1275. X         Blue = (char) floor (Line[x].Blue * 255.0);
  1276. X         putc (Blue, bfp);
  1277. X         }
  1278. X      }
  1279. X   else       /* write out TrueVision Targa 24 format file */
  1280. X      {
  1281. X      for (x = 0; x < Frame.Screen_Width; x++) {
  1282. X         putc((char) floor (Line[x].Blue * 255.0), bfp);
  1283. X         putc((char) floor (Line[x].Green * 255.0), bfp);
  1284. X         putc((char) floor (Line[x].Red * 255.0), bfp);
  1285. X         }
  1286. X      }
  1287. X
  1288. X   if (File_Buffer_Size == 0) {
  1289. X      fflush(bfp);                       /* close and reopen file for */
  1290. X      bfp = freopen(Output_File_Name, "ab", bfp); /* integrity in case we crash*/
  1291. X      }
  1292. X   }
  1293. X
  1294. Xvoid Supersample (result, x, y, Width, Height)
  1295. X   COLOUR *result;
  1296. X   int x, y, Width, Height;
  1297. X   {
  1298. X   COLOUR colour;
  1299. X   register DBL dx, dy, Jitter_X, Jitter_Y;
  1300. X
  1301. X   dx = (DBL) x;
  1302. X   dy = (DBL) y;
  1303. X
  1304. X   Number_Of_Pixels_Supersampled++;
  1305. X
  1306. X   Make_Colour (result, 0.0, 0.0, 0.0);
  1307. X
  1308. X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1309. X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1310. X   Create_Ray (VP_Ray, Frame.Screen_Width, Frame.Screen_Height,
  1311. X             dx + Jitter_X, dy + Jitter_Y);
  1312. X
  1313. X   Trace_Level = 0;
  1314. X   Trace (VP_Ray, &colour);
  1315. X   Clip_Colour (&colour, &colour);
  1316. X   Scale_Colour (&colour, &colour, 0.11111111);
  1317. X   Add_Colour (result, result, &colour);
  1318. X
  1319. X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1320. X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1321. X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X - 0.3333333,
  1322. X                                      dy + Jitter_Y - 0.3333333);
  1323. X   Trace_Level = 0;
  1324. X   Trace (VP_Ray, &colour);
  1325. X   Clip_Colour (&colour, &colour);
  1326. X   Scale_Colour (&colour, &colour, 0.11111111);
  1327. X   Add_Colour (result, result, &colour);
  1328. X
  1329. X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1330. X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1331. X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X - 0.3333333,
  1332. X                                      dy + Jitter_Y);
  1333. X   Trace_Level = 0;
  1334. X   Trace (VP_Ray, &colour);
  1335. X   Clip_Colour (&colour, &colour);
  1336. X   Scale_Colour (&colour, &colour, 0.11111111);
  1337. X   Add_Colour (result, result, &colour);
  1338. X
  1339. X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1340. X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1341. X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X - 0.3333333,
  1342. X                                      dy + Jitter_Y + 0.3333333);
  1343. X   Trace_Level = 0;
  1344. X   Trace (VP_Ray, &colour);
  1345. X   Clip_Colour (&colour, &colour);
  1346. X   Scale_Colour (&colour, &colour, 0.11111111);
  1347. X   Add_Colour (result, result, &colour);
  1348. X
  1349. X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1350. X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1351. X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X,
  1352. X                                      dy + Jitter_Y - 0.3333333);
  1353. X   Trace_Level = 0;
  1354. X   Trace (VP_Ray, &colour);
  1355. X   Clip_Colour (&colour, &colour);
  1356. X   Scale_Colour (&colour, &colour, 0.11111111);
  1357. X   Add_Colour (result, result, &colour);
  1358. X
  1359. X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1360. X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1361. X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X,
  1362. X                                      dy + Jitter_Y + 0.3333333);
  1363. X   Trace_Level = 0;
  1364. X   Trace (VP_Ray, &colour);
  1365. X   Clip_Colour (&colour, &colour);
  1366. X   Scale_Colour (&colour, &colour, 0.11111111);
  1367. X   Add_Colour (result, result, &colour);
  1368. X
  1369. X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1370. X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1371. X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X + 0.3333333,
  1372. X                                      dy + Jitter_Y - 0.3333333);
  1373. X   Trace_Level = 0;
  1374. X   Trace (VP_Ray, &colour);
  1375. X   Clip_Colour (&colour, &colour);
  1376. X   Scale_Colour (&colour, &colour, 0.11111111);
  1377. X   Add_Colour (result, result, &colour);
  1378. X
  1379. X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1380. X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1381. X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X + 0.3333333,
  1382. X                                      dy + Jitter_Y);
  1383. X   Trace_Level = 0;
  1384. X   Trace (VP_Ray, &colour);
  1385. X   Clip_Colour (&colour, &colour);
  1386. X   Scale_Colour (&colour, &colour, 0.11111111);
  1387. X   Add_Colour (result, result, &colour);
  1388. X
  1389. X   Jitter_X = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1390. X   Jitter_Y = (rand3d(x, y) & 0x7FFF) / 32768.0 * 0.33333333 - 0.16666666;
  1391. X   Create_Ray (VP_Ray, Width, Height, dx + Jitter_X + 0.3333333,
  1392. X                                      dy + Jitter_Y + 0.3333333);
  1393. X   Trace_Level = 0;
  1394. X   Trace (VP_Ray, &colour);
  1395. X   Clip_Colour (&colour, &colour);
  1396. X   Scale_Colour (&colour, &colour, 0.11111111);
  1397. X   Add_Colour (result, result, &colour);
  1398. X   }
  1399. X
  1400. Xvoid Start_Tracing ()
  1401. X   {
  1402. X   COLOUR Colour;
  1403. X   RAY Ray;
  1404. X   register int x, y, i, SuperSampleCount;
  1405. X   char Red, Green, Blue, Antialias_Center_Flag;
  1406. X   COLOUR *Previous_Line, *Current_Line, *Temp_Colour_Ptr;
  1407. X   char *Previous_Line_Antialiased_Flags, *Current_Line_Antialiased_Flags,
  1408. X        *Temp_Char_Ptr;
  1409. X
  1410. X
  1411. X   if (Options & VERBOSE) {
  1412. X       printf("Tracing...\n");
  1413. X       fflush (stdout);
  1414. X       }
  1415. X
  1416. X   VP_Ray = &Ray;
  1417. X
  1418. X   Previous_Line = (COLOUR *)   malloc (sizeof (COLOUR)*(Frame.Screen_Width + 1));
  1419. X   Current_Line = (COLOUR *) malloc (sizeof (COLOUR)*(Frame.Screen_Width + 1));
  1420. X
  1421. X   for (i = 0 ; i <= Frame.Screen_Width ; i++) {
  1422. X      Previous_Line[i].Red = 0.0;
  1423. X      Previous_Line[i].Green = 0.0;
  1424. X      Previous_Line[i].Blue = 0.0;
  1425. X
  1426. X      Current_Line[i].Red = 0.0;
  1427. X      Current_Line[i].Green = 0.0;
  1428. X      Current_Line[i].Blue = 0.0;
  1429. X      }
  1430. X
  1431. X   if (Options & ANTIALIAS) {
  1432. X      Previous_Line_Antialiased_Flags =
  1433. X          (char *) malloc (sizeof (char)*(Frame.Screen_Width + 1));
  1434. X      Current_Line_Antialiased_Flags =
  1435. X          (char *)  malloc (sizeof (char)*(Frame.Screen_Width + 1));
  1436. X
  1437. X      for (i = 0 ; i <= Frame.Screen_Width ; i++) {
  1438. X         Previous_Line_Antialiased_Flags[i] = 0;
  1439. X         Current_Line_Antialiased_Flags[i] = 0;
  1440. X         }
  1441. X      }
  1442. X
  1443. X   Ray.Initial = Frame.View_Point.Location;
  1444. X
  1445. X   for (y = (Options & ANTIALIAS)?First_Line-1:First_Line ; y<Last_Line ; y++) {
  1446. X
  1447. X      TEST_ABORT
  1448. X
  1449. X      if (Options & VERBOSE)
  1450. X         printf ("Line %3d", y);
  1451. X
  1452. X      if (Options & ANTIALIAS)
  1453. X         SuperSampleCount = 0;
  1454. X
  1455. X      for (x = 0 ; x < Frame.Screen_Width ; x++) {
  1456. X         Number_Of_Pixels++;
  1457. X         if (Stop_Flag) {
  1458. X            close_all();
  1459. X            exit(0);
  1460. X            }
  1461. X
  1462. X         Create_Ray (VP_Ray, Frame.Screen_Width, Frame.Screen_Height, (DBL) x, (DBL) y);
  1463. X         Trace_Level = 0;
  1464. X         Trace (&Ray, &Colour);
  1465. X         Clip_Colour (&Colour, &Colour);
  1466. X
  1467. X         Current_Line[x] = Colour;
  1468. X
  1469. X         if (Options & ANTIALIAS) {
  1470. X            Antialias_Center_Flag = 0;
  1471. X            Current_Line_Antialiased_Flags[x] = 0;
  1472. X
  1473. X            if (x != 0) {
  1474. X               if (Colour_Distance (&Current_Line[x-1], &Current_Line[x])
  1475. X                   >= Frame.Antialias_Threshold) {
  1476. X                  Antialias_Center_Flag = 1;
  1477. X                  if (!(Current_Line_Antialiased_Flags[x-1])) {
  1478. X                     Supersample (&Current_Line[x-1], 
  1479. X                                  x-1, y, Frame.Screen_Width, Frame.Screen_Height);
  1480. X                     Current_Line_Antialiased_Flags[x-1] = 1;
  1481. X                     SuperSampleCount++;
  1482. X                     }
  1483. X                  }
  1484. X               }
  1485. X
  1486. X            if (y != First_Line-1) {
  1487. X               if (Colour_Distance (&Previous_Line[x], &Current_Line[x])
  1488. X                    >= Frame.Antialias_Threshold) {
  1489. X                  Antialias_Center_Flag = 1;
  1490. X                  if (!(Previous_Line_Antialiased_Flags[x])) {
  1491. X                     Supersample (&Previous_Line[x],
  1492. X                                  x, y-1, Frame.Screen_Width, Frame.Screen_Height);
  1493. X                     Previous_Line_Antialiased_Flags[x] = 1;
  1494. X                     SuperSampleCount++;
  1495. X                     }
  1496. X                  }
  1497. X               }
  1498. X
  1499. X            if (Antialias_Center_Flag) {
  1500. X               Supersample (&Current_Line[x],
  1501. X                            x, y, Frame.Screen_Width, Frame.Screen_Height);
  1502. X               Current_Line_Antialiased_Flags[x] = 1;
  1503. X               Colour = Current_Line[x];
  1504. X               SuperSampleCount++;
  1505. X               }
  1506. X            }
  1507. X
  1508. X         if (y != First_Line-1) {
  1509. X            Red = (char) (Colour.Red * 255.0);
  1510. X            Green = (char) (Colour.Green * 255.0);
  1511. X            Blue = (char) (Colour.Blue * 255.0);
  1512. X
  1513. X            if (Options & DISPLAY)
  1514. X               display_plot (x, y, Red, Green, Blue);
  1515. X            }
  1516. X         }
  1517. X
  1518. X      if ((Options & DISKWRITE) || (Options & TARGA))
  1519. X         if (y > First_Line) {
  1520. X            Write_Line (Previous_Line, y-1);
  1521. X         }
  1522. X
  1523. X      if (Options & VERBOSE)
  1524. X         if (Options & ANTIALIAS)
  1525. X            printf (" supersampled %d times\n", SuperSampleCount);
  1526. X         else
  1527. X            putchar ('\n');
  1528. X
  1529. X      Temp_Colour_Ptr = Previous_Line;
  1530. X      Previous_Line = Current_Line;
  1531. X      Current_Line = Temp_Colour_Ptr;
  1532. X
  1533. X      Temp_Char_Ptr = Previous_Line_Antialiased_Flags;
  1534. X      Previous_Line_Antialiased_Flags = Current_Line_Antialiased_Flags;
  1535. X      Current_Line_Antialiased_Flags = Temp_Char_Ptr;
  1536. X      }
  1537. X
  1538. X   if ((Options & DISKWRITE) || (Options & TARGA)) {
  1539. X      Write_Line (Previous_Line, Last_Line - 1);
  1540. X      }
  1541. X   }
  1542. X
  1543. Xvoid Trace (Ray, Colour)
  1544. X   RAY *Ray;
  1545. X   COLOUR *Colour;
  1546. X   {
  1547. X   COLOUR Temp_Colour, Surface_Colour;
  1548. X   OBJECT *Object;
  1549. X   VECTOR Surface_Normal;
  1550. X   INTERSECTION *Local_Intersection, *New_Intersection;
  1551. X   register int Intersection_Found;
  1552. X   DBL Normal_Direction;
  1553. X
  1554. X   Number_Of_Rays++;
  1555. X   if (Frame.Fog_Distance == 0.0) {
  1556. X      Make_Colour (&Temp_Colour, 0.0, 0.0, 0.0);
  1557. X      }
  1558. X   else
  1559. X      Temp_Colour = Frame.Fog_Colour;
  1560. X
  1561. X   Intersection_Found = FALSE;
  1562. X   Local_Intersection = NULL;
  1563. X
  1564. X   if (Trace_Level > MAX_TRACE_LEVEL)
  1565. X      return;
  1566. X
  1567. X    /* What objects does this ray intersect? */
  1568. X   for (Object = Frame.Objects ; 
  1569. X        Object != NULL ;
  1570. X        Object = Object -> Next_Object) {
  1571. X
  1572. X      if (New_Intersection = Intersection (Object, Ray)) {
  1573. X         if (Intersection_Found) {
  1574. X            if (Local_Intersection -> Depth > New_Intersection -> Depth) {
  1575. X               free (Local_Intersection);
  1576. X               Local_Intersection = New_Intersection;
  1577. X               }
  1578. X            else
  1579. X               free (New_Intersection);
  1580. X            }
  1581. X         else
  1582. X            Local_Intersection = New_Intersection;
  1583. X
  1584. X         Intersection_Found = TRUE;
  1585. X         }
  1586. X      }
  1587. X
  1588. X   if (Intersection_Found) {
  1589. X      Make_Colour (&Temp_Colour, 0.0, 0.0, 0.0);
  1590. X      Make_Colour (&Surface_Colour, 0.0, 0.0, 0.0);
  1591. X
  1592. X      if (Quality > 5)
  1593. X         Colour_At (&Surface_Colour, Local_Intersection->Object,
  1594. X                    &Local_Intersection -> Point);
  1595. X      else
  1596. X         Surface_Colour = Local_Intersection->Object->Object_Colour;
  1597. X
  1598. X
  1599. X      if (Quality <= 1)
  1600. X         Temp_Colour = Surface_Colour;
  1601. X      else {
  1602. X         Normal (&Surface_Normal, (OBJECT *) Local_Intersection -> Shape,
  1603. X                 &Local_Intersection -> Point);
  1604. X         VDot (Normal_Direction, Surface_Normal, Ray->Direction);
  1605. X         if (Normal_Direction > 0.0) {
  1606. X            VScale (Surface_Normal, Surface_Normal, -1.0);
  1607. X            }
  1608. X
  1609. X         Ambient (Local_Intersection -> Object, &Local_Intersection -> Point,
  1610. X                    &Surface_Colour, &Temp_Colour);
  1611. X         Diffuse (Local_Intersection -> Object, &Local_Intersection -> Point, Ray,
  1612. X                    &Surface_Normal, &Surface_Colour, &Temp_Colour);
  1613. X
  1614. X         if (Quality > 7) {
  1615. X            Transmit (Local_Intersection -> Object, &Local_Intersection -> Point, Ray,
  1616. X                      &Surface_Normal, &Surface_Colour, &Temp_Colour);
  1617. X            Reflect (Local_Intersection -> Object, &Local_Intersection -> Point, Ray,
  1618. X                     &Surface_Normal, &Temp_Colour);
  1619. X            Refract (Local_Intersection -> Object, &Local_Intersection -> Point, Ray,
  1620. X                     &Surface_Normal, &Temp_Colour);
  1621. X
  1622. X            if (Frame.Fog_Distance != 0.0)
  1623. X               Fog (Local_Intersection->Depth, &Frame.Fog_Colour, Frame.Fog_Distance,
  1624. X                    &Temp_Colour);
  1625. X            }
  1626. X         }
  1627. X      free (Local_Intersection);
  1628. X      }
  1629. X
  1630. X   *Colour = Temp_Colour;
  1631. X   }
  1632. X
  1633. END_OF_FILE
  1634. if test 16452 -ne `wc -c <'src/render.c'`; then
  1635.     echo shar: \"'src/render.c'\" unpacked with wrong size!
  1636. fi
  1637. # end of 'src/render.c'
  1638. fi
  1639. if test -f 'src/trace.c' -a "${1}" != "-c" ; then 
  1640.   echo shar: Will not clobber existing file \"'src/trace.c'\"
  1641. else
  1642. echo shar: Extracting \"'src/trace.c'\" \(15243 characters\)
  1643. sed "s/^X//" >'src/trace.c' <<'END_OF_FILE'
  1644. X/*****************************************************************************
  1645. X*
  1646. X*                                     trace.c
  1647. X*
  1648. X*   from DKBTrace (c) 1990  David Buck
  1649. X*
  1650. X*  This module contains the entry routine for the raytracer and the code to
  1651. X*  parse the parameters on the command line.
  1652. X*
  1653. X*
  1654. X* This software is freely distributable. The source and/or object code may be
  1655. X* copied or uploaded to communications services so long as this notice remains
  1656. X* at the top of each file.  If any changes are made to the program, you must
  1657. X* clearly indicate in the documentation and in the programs startup message
  1658. X* who it was who made the changes. The documentation should also describe what
  1659. X* those changes were. This software may not be included in whole or in
  1660. X* part into any commercial package without the express written consent of the
  1661. X* author.  It may, however, be included in other public domain or freely
  1662. X* distributed software so long as the proper credit for the software is given.
  1663. X*
  1664. X* This software is provided as is without any guarantees or warranty. Although
  1665. X* the author has attempted to find and correct any bugs in the software, he
  1666. X* is not responsible for any damage caused by the use of the software.  The
  1667. X* author is under no obligation to provide service, corrections, or upgrades
  1668. X* to this package.
  1669. X*
  1670. X* Despite all the legal stuff above, if you do find bugs, I would like to hear
  1671. X* about them.  Also, if you have any comments or questions, you may contact me
  1672. X* at the following address:
  1673. X*
  1674. X*     David Buck
  1675. X*     22C Sonnet Cres.
  1676. X*     Nepean Ontario
  1677. X*     Canada, K2H 8W7
  1678. X*
  1679. X*  I can also be reached on the following bulleton boards:
  1680. X*
  1681. X*     ATX              (613) 526-4141
  1682. X*     OMX              (613) 731-3419
  1683. X*     Mystic           (613) 731-0088 or (613) 731-6698
  1684. X*
  1685. X*  Fidonet:   1:163/109.9
  1686. X*  Internet:  David_Buck@Carleton.CA
  1687. X*
  1688. X*  IBM Port by Aaron A. Collins. Aaron may be reached on the following BBS'es:
  1689. X*
  1690. X*     Lattice BBS                      (708) 916-1200
  1691. X*     The Information Exchange BBS     (708) 945-5575
  1692. X*     Stillwaters BBS                  (708) 403-2826
  1693. X*
  1694. X*****************************************************************************/
  1695. X
  1696. X#include <ctype.h>
  1697. X#include "frame.h"        /* common to ALL modules in this program */
  1698. X#include "dkbproto.h"
  1699. X
  1700. X#define MAX_FILE_NAMES 1
  1701. Xunsigned long Options;
  1702. Xint Quality;
  1703. X
  1704. XFILE *bfp;
  1705. X
  1706. XFILE *Input_File, *Token_File, *Symbol_File, *Data_File;
  1707. Xextern FRAME Frame;
  1708. X
  1709. Xstatic char *File_Names[MAX_FILE_NAMES];
  1710. Xchar Input_File_Name[FILE_NAME_LENGTH], Output_File_Name[FILE_NAME_LENGTH];
  1711. Xchar *Output_File_Buffer;
  1712. Xint File_Buffer_Size;
  1713. Xstatic int Number_Of_Files;
  1714. XDBL VTemp;
  1715. XDBL Antialias_Threshold;
  1716. Xint First_Line, Last_Line;
  1717. X
  1718. X/* Stats kept by the ray tracer: */
  1719. Xlong Number_Of_Pixels, Number_Of_Rays, Number_Of_Pixels_Supersampled;
  1720. Xlong Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded;
  1721. Xlong Ray_Plane_Tests, Ray_Plane_Tests_Succeeded;
  1722. Xlong Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded;
  1723. Xlong Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded;
  1724. Xlong Bounding_Region_Tests, Bounding_Region_Tests_Succeeded;
  1725. Xlong Calls_To_Noise, Calls_To_DNoise;
  1726. Xlong Shadow_Ray_Tests, Shadow_Rays_Succeeded;
  1727. Xlong Reflected_Rays_Traced, Refracted_Rays_Traced;
  1728. Xlong Transmitted_Rays_Traced;
  1729. X
  1730. X
  1731. Xvoid main (argc, argv)
  1732. X  int argc;
  1733. X  char **argv;
  1734. X  {
  1735. X  register int i;
  1736. X  char temp[2];
  1737. X  
  1738. X  printf ("\n\n              DKB Ray Trace   Version 2.01\n");
  1739. X  printf ("              ----------------------------\n\n");
  1740. X  printf ("             Copyright (c) 1990  David Buck\n\n");
  1741. X  printf ("  Written by:\n");
  1742. X  printf ("  David K. Buck\n");
  1743. X  printf ("  22C Sonnet Cr.  Nepean, Ontario\n");
  1744. X  printf ("  Canada, K2H 8W7\n\n");
  1745. X  printf ("  This program is freely distributable.\n");
  1746. X
  1747. X  printf ("\n  Conversion to IBM P.C. w/TARGA output \n");
  1748. X  printf ("    and various improvements by Aaron A. Collins\n\n");
  1749. X
  1750. X  printf ("  GIF format file reader by Steve A. Bennett\n\n");
  1751. X
  1752. X  printf ("  Noise and DNoise functions by Robert Skinner\n\n");
  1753. X
  1754. X/* Parse the command line parameters */
  1755. X  if (argc == 1)
  1756. X    {
  1757. X    printf ("\nUsage:");
  1758. X    printf ("\n   trace  [+/-] Option1 [+/-] Option2");
  1759. X    printf ("\n");
  1760. X    printf ("\n Options:");
  1761. X    printf ("\n    d  = display");
  1762. X    printf ("\n    v  = verbose");
  1763. X    printf ("\n    p  = prompt exit");
  1764. X    printf ("\n    x  = enable early exit by key hit");
  1765. X    printf ("\n    f  = write DKB/QRT format output file");
  1766. X    printf ("\n    t  = write TARGA format output file");
  1767. X    printf ("\n    a  = perform antialiasing");
  1768. X/*  printf ("\n    z  = debug mode");    */
  1769. X    printf ("\n    qx = image quality 0=rough, 9=full");
  1770. X    printf ("\n    wxxx = width of the screen");
  1771. X    printf ("\n    hxxx = height of the screen");
  1772. X    printf ("\n    sxxx = start at line number xxx");
  1773. X    printf ("\n    exxx = end at line number xxx");
  1774. X    printf ("\n    bxxx = Use xxx kilobytes for output file buffer space");
  1775. X    printf ("\n    ifilename = input file name");
  1776. X    printf ("\n    ofilename = output file name");
  1777. X    printf ("\n\n");
  1778. X    exit(0);
  1779. X    }
  1780. X
  1781. X  bfp = NULL;
  1782. X  File_Buffer_Size = 0;
  1783. X  Options = 0;
  1784. X  Quality = 9;
  1785. X  Number_Of_Files = 0;
  1786. X  First_Line = 0;
  1787. X  Last_Line = -1;
  1788. X
  1789. X  Number_Of_Pixels = 0L;
  1790. X  Number_Of_Rays = 0L;
  1791. X  Number_Of_Pixels_Supersampled = 0L;
  1792. X  Ray_Sphere_Tests = 0L;
  1793. X  Ray_Sphere_Tests_Succeeded = 0L;
  1794. X  Ray_Plane_Tests = 0L;
  1795. X  Ray_Plane_Tests_Succeeded = 0L;
  1796. X  Ray_Triangle_Tests = 0L;
  1797. X  Ray_Triangle_Tests_Succeeded = 0L;
  1798. X  Ray_Quadric_Tests = 0L;
  1799. X  Ray_Quadric_Tests_Succeeded = 0L;
  1800. X  Bounding_Region_Tests = 0L;
  1801. X  Bounding_Region_Tests_Succeeded = 0L;
  1802. X  Calls_To_Noise = 0L;
  1803. X  Calls_To_DNoise = 0L;
  1804. X  Shadow_Ray_Tests = 0L;
  1805. X  Shadow_Rays_Succeeded = 0L;
  1806. X  Reflected_Rays_Traced = 0L;
  1807. X  Refracted_Rays_Traced = 0L;
  1808. X  Transmitted_Rays_Traced = 0L;
  1809. X
  1810. X  Frame.Screen_Height = 100;
  1811. X  Frame.Screen_Width = 100;
  1812. X
  1813. X  Antialias_Threshold = 0.3;
  1814. X  strcpy (&Input_File_Name[0], "object.data");
  1815. X
  1816. X/* Read the default parameters from trace.def */
  1817. X  get_defaults();
  1818. X
  1819. X  strcpy (&Output_File_Name[0], "data.dis");
  1820. X
  1821. X  if (Options & TARGA)
  1822. X     strcpy (&Output_File_Name[0], "data.tga");
  1823. X
  1824. X  for (i = 1 ; i < argc ; i++ )
  1825. X    if ((*argv[i] == '+') || (*argv[i] == '-'))
  1826. X      parse_option(argv[i]);
  1827. X    else
  1828. X      parse_file_name(argv[i]);
  1829. X
  1830. X   if (Last_Line == -1)
  1831. X      Last_Line = Frame.Screen_Height;
  1832. X
  1833. X   Print_Options();
  1834. X
  1835. X/* Tokenize the input file */
  1836. X  if ((Input_File = fopen (Input_File_Name, "r")) == NULL)
  1837. X    {
  1838. X    printf ("Cannot open input file\n");
  1839. X    exit (0);
  1840. X    }
  1841. X
  1842. X  if ((Token_File = fopen ("Token.data", "w")) == NULL)
  1843. X    {
  1844. X    printf ("Cannot open token file for write\n");
  1845. X    exit (0);
  1846. X    }
  1847. X
  1848. X  if ((Symbol_File = fopen ("Symbols.data", "w")) == NULL)
  1849. X    {
  1850. X    printf ("Cannot open string file for writing\n");
  1851. X    exit(0);
  1852. X    }
  1853. X
  1854. X  printf ("Tokenizing...\n");
  1855. X  Tokenize (Input_File_Name, Input_File, Symbol_File, Token_File);
  1856. X  fclose (Input_File);
  1857. X  fclose (Token_File);
  1858. X  fclose (Symbol_File);
  1859. X
  1860. X/* parse the tokenize file */
  1861. X  if ((Token_File = fopen ("Token.data", "r")) == NULL)
  1862. X    exit (0);
  1863. X
  1864. X  if ((Symbol_File = fopen ("Symbols.data", "r")) == NULL)
  1865. X    {
  1866. X    printf ("Cannot open string file for reading\n");
  1867. X    exit(0);
  1868. X    }
  1869. X
  1870. X  printf ("Parsing...\n");
  1871. X  Parse (Token_File, &Frame);
  1872. X  fclose (Token_File);
  1873. X
  1874. X/* Get things ready for ray tracing */
  1875. X  if ((Options & DISKWRITE) || (Options & TARGA)) {
  1876. X    bfp = fopen (&Output_File_Name[0], "wb");
  1877. X    if (bfp == NULL) {
  1878. X        printf ("Cannot open output file\n");
  1879. X        exit (0);
  1880. X        }
  1881. X    if (File_Buffer_Size != 0) {
  1882. X       Output_File_Buffer = malloc (File_Buffer_Size);
  1883. X       setvbuf (bfp, Output_File_Buffer, _IOFBF, File_Buffer_Size);
  1884. X       }
  1885. X
  1886. X    if (Options & TARGA) {        /* Prefix TARGA format file header */
  1887. X    for (i = 0; i < 10; i++)    /* 00, 00, 02, then 7 00's... */
  1888. X        if (i == 2)
  1889. X         putc(i, bfp);
  1890. X        else putc(0, bfp);
  1891. X        temp[0] = First_Line % 256;    /* y origin is set to "First_Line" */
  1892. X        putc (temp[0], bfp);
  1893. X        temp[0] = First_Line / 256;
  1894. X        putc (temp[0], bfp);
  1895. X        }
  1896. X
  1897. X    temp[0] = Frame.Screen_Width % 256;    /* write this to either file type */
  1898. X    putc (temp[0], bfp);
  1899. X    temp[0] = Frame.Screen_Width / 256;
  1900. X    putc (temp[0], bfp);
  1901. X    temp[0] = Frame.Screen_Height % 256;
  1902. X    putc (temp[0], bfp);
  1903. X    temp[0] = Frame.Screen_Height / 256;
  1904. X    putc (temp[0], bfp);
  1905. X
  1906. X    if (Options & TARGA) {    /* now finish the TARGA format file header */
  1907. X    putc(24, bfp);        /* 24 bits/pixel (16 million colors!) */
  1908. X    putc(32, bfp);        /* Not sure about this one, "out of 32" ? */
  1909. X    }
  1910. X    }
  1911. X
  1912. X  if (Options & DISPLAY)
  1913. X    {
  1914. X    printf ("Displaying...\n");
  1915. X    display_init();
  1916. X    }
  1917. X
  1918. X  pq_init();
  1919. X  Initialize_Noise();
  1920. X
  1921. X/* Ok, go for it - trace the picture */
  1922. X  Start_Tracing ();
  1923. X
  1924. X/* Wait for a CR if the user requested it. */
  1925. X
  1926. X/* Clean up and leave */
  1927. X  display_finished();
  1928. X
  1929. X  close_all ();
  1930. X  print_stats();
  1931. X  }
  1932. X
  1933. X/* Close all the stuff that has been opened. */
  1934. Xvoid close_all ()
  1935. X   {
  1936. X   if (Options & DISPLAY)
  1937. X     display_close();
  1938. X
  1939. X   if (bfp)
  1940. X      fclose (bfp);
  1941. X   }
  1942. X
  1943. X/* Read the default parameters from trace.def*/
  1944. Xvoid get_defaults()
  1945. X  {
  1946. X  read_options ("trace.def");
  1947. X  }
  1948. X
  1949. Xvoid read_options (file_name)
  1950. X  char *file_name;
  1951. X  {
  1952. X  FILE *default_file;
  1953. X  register int c, String_Index, Option_Started;
  1954. X  char Option_String[80];
  1955. X
  1956. X  String_Index = 0;
  1957. X  Option_Started = FALSE;
  1958. X  if (default_file = fopen(file_name, "r"))
  1959. X    while ((c = getc(default_file)) != EOF)
  1960. X      {
  1961. X      if (Option_Started)
  1962. X        if (isspace(c))
  1963. X          {
  1964. X          Option_String[String_Index] = '\0';
  1965. X          parse_option (Option_String);
  1966. X          Option_Started = FALSE;
  1967. X          }
  1968. X       else
  1969. X         Option_String[String_Index++] = (char) c;
  1970. X
  1971. X      else /* Option_Started */
  1972. X
  1973. X        if ((c == (int) '-') || (c == (int) '+'))
  1974. X          {
  1975. X          String_Index = 0;
  1976. X          Option_String[String_Index++] = (char) c;
  1977. X          Option_Started = TRUE;
  1978. X          }
  1979. X        else
  1980. X          if (!isspace(c))
  1981. X            {
  1982. X            printf ("\nBad default file format.  Offending char: (%c), val: %d.\n", (char) c, c);
  1983. X            exit (0);
  1984. X        }
  1985. X      }
  1986. X
  1987. X  if (Option_Started)
  1988. X    {
  1989. X    Option_String[String_Index] = '\0';
  1990. X    parse_option (Option_String);
  1991. X    }
  1992. X  }
  1993. X
  1994. X/* parse the command line parameters */
  1995. Xvoid parse_option (Option_String)
  1996. X  char *Option_String;
  1997. X  {
  1998. X  register int Add_Option;
  1999. X  unsigned long Option_Number;
  2000. X  DBL threshold;
  2001. X
  2002. X  if (*(Option_String++) == '-')
  2003. X    Add_Option = FALSE;
  2004. X  else
  2005. X    Add_Option = TRUE;
  2006. X
  2007. X  switch (*Option_String)
  2008. X    {
  2009. X    case 'B':
  2010. X    case 'b':  sscanf (&Option_String[1], "%d", &File_Buffer_Size);
  2011. X               File_Buffer_Size *= 1024;
  2012. X               if (File_Buffer_Size < BUFSIZ)
  2013. X                  File_Buffer_Size = BUFSIZ;
  2014. X               Option_Number = 0;
  2015. X               break;
  2016. X
  2017. X    case 'D':
  2018. X    case 'd':  Option_Number = DISPLAY;
  2019. X               break;
  2020. X
  2021. X    case 'V':
  2022. X    case 'v':  Option_Number = VERBOSE;
  2023. X               break;
  2024. X
  2025. X    case 'W':
  2026. X    case 'w':  sscanf (&Option_String[1], "%d", &Frame.Screen_Width);
  2027. X           Option_Number = 0;
  2028. X               break;
  2029. X
  2030. X    case 'H':
  2031. X    case 'h':  sscanf (&Option_String[1], "%d", &Frame.Screen_Height);
  2032. X           Option_Number = 0;
  2033. X               break;
  2034. X
  2035. X    case 'F':
  2036. X    case 'f':  Option_Number = DISKWRITE;
  2037. X               break;
  2038. X
  2039. X    case 'P':
  2040. X    case 'p':  Option_Number = PROMPTEXIT;
  2041. X               break;
  2042. X
  2043. X    case 'I':
  2044. X    case 'i':  strncpy (&Input_File_Name[0], &Option_String[1], FILE_NAME_LENGTH);
  2045. X           Option_Number = 0;
  2046. X               break;
  2047. X
  2048. X    case 'O':
  2049. X    case 'o':  strncpy (&Output_File_Name[0], &Option_String[1], FILE_NAME_LENGTH);
  2050. X           Option_Number = 0;
  2051. X               break;
  2052. X
  2053. X    case 'A':
  2054. X    case 'a':  Option_Number = ANTIALIAS;
  2055. X               if (sscanf (&Option_String[1], DBL_FORMAT_STRING, &threshold) != EOF)
  2056. X                   Antialias_Threshold = threshold;
  2057. X               break;
  2058. X
  2059. X    case 'X':
  2060. X    case 'x':  Option_Number = EXITENABLE;
  2061. X               break;
  2062. X
  2063. X    case 'S':
  2064. X    case 's':  sscanf (&Option_String[1], "%d", &First_Line);
  2065. X           Option_Number = 0;
  2066. X               break;
  2067. X
  2068. X    case 'E':
  2069. X    case 'e':  sscanf (&Option_String[1], "%d", &Last_Line);
  2070. X           Option_Number = 0;
  2071. X               break;
  2072. X
  2073. X    case 'Q':
  2074. X    case 'q':  sscanf (&Option_String[1], "%d", &Quality);
  2075. X           Option_Number = 0;
  2076. X               break;
  2077. X
  2078. X    case 'T':
  2079. X    case 't':  Option_Number = TARGA;
  2080. X               break;
  2081. X
  2082. X    case 'Z':
  2083. X    case 'z':  Option_Number = DEBUGGING;
  2084. X               break;
  2085. X
  2086. X    default:   printf ("\nInvalid option: %s\n\n", --Option_String);
  2087. X           Option_Number = 0;
  2088. X    }
  2089. X
  2090. X  if (Option_Number != 0)
  2091. X      if (Add_Option)
  2092. X           Options |= Option_Number;
  2093. X      else Options &= ~Option_Number;
  2094. X  }
  2095. X
  2096. Xvoid Print_Options()
  2097. X   {
  2098. X   printf ("Options in effect: ");
  2099. X   if (Options & DISPLAY)
  2100. X      printf ("+d ");
  2101. X   else
  2102. X      printf ("-d ");
  2103. X
  2104. X   if (Options & VERBOSE)
  2105. X      printf ("+v ");
  2106. X   else
  2107. X      printf ("-v ");
  2108. X
  2109. X   if (Options & DISKWRITE)
  2110. X      printf ("+f ");
  2111. X   else
  2112. X      printf ("-f ");
  2113. X
  2114. X   if (Options & PROMPTEXIT)
  2115. X      printf ("+p ");
  2116. X   else
  2117. X      printf ("-p ");
  2118. X
  2119. X   if (Options & TARGA)
  2120. X      printf ("+t ");
  2121. X   else
  2122. X      printf ("-t ");
  2123. X
  2124. X   if (Options & EXITENABLE)
  2125. X      printf ("+x ");
  2126. X   else
  2127. X      printf ("-x ");
  2128. X
  2129. X   if (Options & ANTIALIAS)
  2130. X      printf ("+a%f ", Antialias_Threshold);
  2131. X   else
  2132. X      printf ("-a ");
  2133. X
  2134. X   if (File_Buffer_Size != 0)
  2135. X      printf ("-b%d ", File_Buffer_Size/1024);
  2136. X
  2137. X   printf ("-q%d -w%d -h%d -s%d -e%d -i%s ",
  2138. X           Quality, Frame.Screen_Width, Frame.Screen_Height,
  2139. X           First_Line, Last_Line, Input_File_Name);
  2140. X
  2141. X   if (Options & DISKWRITE)
  2142. X      printf ("-o%s", Output_File_Name);
  2143. X
  2144. X   printf ("\n");
  2145. X   }
  2146. X
  2147. Xvoid parse_file_name (File_Name)
  2148. X  char *File_Name;
  2149. X  {
  2150. X  File_Names [Number_Of_Files++] = File_Name;  
  2151. X  if (Number_Of_Files > MAX_FILE_NAMES)
  2152. X    {
  2153. X    printf ("\nOnly %d file names are allowed in a command line.", 
  2154. X             MAX_FILE_NAMES);
  2155. X    exit(0);
  2156. X    }
  2157. X  read_options (File_Name);
  2158. X  }
  2159. X
  2160. Xvoid print_stats()
  2161. X   {
  2162. X   printf ("                  Statistics\n");
  2163. X   printf ("                  ----------\n\n");
  2164. X   printf ("# Rays:  %10ld    # Pixels:  %10ld  # Pixels supersampled: %10ld\n\n",
  2165. X            Number_Of_Rays, Number_Of_Pixels, Number_Of_Pixels_Supersampled);
  2166. X
  2167. X   printf ("\nIntersection Tests:\n\n");
  2168. X   printf ("   Type       Tests    Succeeded\n");
  2169. X   printf ("   ----    ----------  ----------\n\n");
  2170. X   printf ("  Sphere   %10ld  %10ld\n", Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded);
  2171. X   printf ("  Plane    %10ld  %10ld\n", Ray_Plane_Tests, Ray_Plane_Tests_Succeeded);
  2172. X   printf ("  Triangle %10ld  %10ld\n", Ray_Triangle_Tests, Ray_Triangle_Tests_Succeeded);
  2173. X   printf ("  Quadric  %10ld  %10ld\n", Ray_Quadric_Tests, Ray_Quadric_Tests_Succeeded);
  2174. X   printf ("  Bounds   %10ld  %10ld\n\n", Bounding_Region_Tests, Bounding_Region_Tests_Succeeded);
  2175. X   printf ("  Calls to Noise:   %10ld\n", Calls_To_Noise);
  2176. X   printf ("  Calls to DNoise:  %10ld\n", Calls_To_DNoise);
  2177. X   printf ("  Shadow Ray Tests: %10ld     Blocking Objects Found:  %10ld\n",
  2178. X              Shadow_Ray_Tests, Shadow_Rays_Succeeded);
  2179. X   printf ("  Reflected Rays:   %10ld\n", Reflected_Rays_Traced);
  2180. X   printf ("  Refracted Rays:   %10ld\n", Refracted_Rays_Traced);
  2181. X   printf ("  Transmitted Rays: %10ld\n", Transmitted_Rays_Traced);
  2182. X   }
  2183. END_OF_FILE
  2184. if test 15243 -ne `wc -c <'src/trace.c'`; then
  2185.     echo shar: \"'src/trace.c'\" unpacked with wrong size!
  2186. fi
  2187. # end of 'src/trace.c'
  2188. fi
  2189. echo shar: End of archive 5 \(of 10\).
  2190. cp /dev/null ark5isdone
  2191. MISSING=""
  2192. for I in 1 2 3 4 5 6 7 8 9 10 ; do
  2193.     if test ! -f ark${I}isdone ; then
  2194.     MISSING="${MISSING} ${I}"
  2195.     fi
  2196. done
  2197. if test "${MISSING}" = "" ; then
  2198.     echo You have unpacked all 10 archives.
  2199.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2200. else
  2201.     echo You still need to unpack the following archives:
  2202.     echo "        " ${MISSING}
  2203. fi
  2204. ##  End of shell archive.
  2205. exit 0
  2206. -- 
  2207. Mail submissions (sources or binaries) to <amiga@uunet.uu.net>.
  2208. Mail comments to the moderator at <amiga-request@uunet.uu.net>.
  2209. Post requests for sources, and general discussion to comp.sys.amiga.
  2210.